package gameEngine;

import classInterfaces.IDots;
import classInterfaces.IField;
import classInterfaces.IPlayer;
import gameEngine.Dot;
import Exceptions.IncorrectInputException;

public class Field implements IField {
	private IDots[][] field;
	private IPlayer[] players;

	private IDots[][] getField() {
		return field;
	}

	private IPlayer[] getPlayersArray() {
		return players;
	}

	/**
	 * 
	 * @param x
	 *            number of rows
	 * @param y
	 *            number of columns
	 * @param players
	 *            array of players
	 * @throws IncorrectInputException
	 *             if input is not correct
	 */

	private Field(int x, int y, IPlayer[] players)
			throws IncorrectInputException {
		// players init
		if (players == null || players.length <= 0)
			throw new IncorrectInputException("Not valid array of players");
		else {
			this.players = new Player[players.length];
			for (int i = 0; i < players.length; i++) {
				if (players[i] == null)
					throw new IncorrectInputException(
							"Not valid player in array of players");
				this.players[i] = players[i];
			}
		}
		// field init
		if (x <= 0 || y <= 0)
			throw new IncorrectInputException("Size of field not valid");
		else {
			field = new Dot[x][y];
			for (int row = 0; row < x; row++) {
				for (int col = 0; col < y; col++) {
					field[row][col] = new Dot();
				}
			}
		}
	}

	/**
	 * Copies fields from object j to this object
	 * 
	 * @param g
	 *            - Field to be copied
	 * @throws IncorrectInputException
	 */
	public void copy(Field g) throws IncorrectInputException {
		if (g == null || g.getField() == null || g.getField().length == 0
				|| g.getField()[0].length == 0)
			throw new IncorrectInputException();
		IDots[][] gField = g.getField();
		field = new Dot[gField.length][gField[0].length];
		for (int row = 0; row < gField.length; row++) {
			for (int col = 0; col < gField[0].length; col++) {
				if (gField[row][col] == null)
					throw new IncorrectInputException();
				field[row][col] = gField[row][col];
			}
		}
		if (g.getPlayersArray() == null || g.getPlayersArray().length == 0)
			throw new IncorrectInputException();
		players = new Player[g.getPlayersArray().length];
		for (int i = 0; i < g.getPlayersArray().length; i++) {
			if (g.getPlayersArray()[i] == null)
				throw new IncorrectInputException();
			players[i] = g.getPlayersArray()[i];
		}
	}

	@Override
	public void connectDot(int[] coordinates, char direction) {
		// TODO Auto-generated method stub

	}

	@Override
	public Player announceWinner() {
		return null;
	}

	/**
	 * 
	 * @param x
	 *            number of rows
	 * @param y
	 *            number of columns
	 * @param players
	 *            array of players
	 * @throws IncorrectInputException
	 *             if input is not correct
	 */
	public static Field createField(int x, int y, Player[] players)
			throws IncorrectInputException {
		return new Field(x, y, players);
	}

	/**
	 * Function to help GUI drawing
	 * 
	 * @param d
	 *            a dot, which properties will be returned
	 * @return array of boolean values wheter dot can be connected with another
	 *         dot
	 */
	private boolean[] dotProperties(IDots d) {
		return new boolean[] { d.hasMovedRight(), d.hasMovedUp() };
	}

	/**
	 * Restricts dots on the border of the field from connecting Upwards and to
	 * the Right
	 */
	private void restrictBorderDots() {
		for (int row = 0; row < field.length; row++) {
			field[row][field[0].length - 1].moveRight(false);
		}
		for (int col = 0; col < field[0].length; col++) {
			field[0][col].moveUp(false);
		}
	}

	public int getRowLength() {
		return field.length;
	}

	public int getColumnLength() {
		return field[0].length;
	}
	
	public Dot getDot(int row, int column) throws IncorrectInputException {
		if(row < 0 || row >= field.length || column < 0 || column >= field[row].length)
			throw new IncorrectInputException();
		
		
		return new Dot(field[row][column]);
	}

}
